#!/bin/bash
# + -- --=[Sn1per Community Edition by @xer0dayz
# + -- --=[https://xerosecurity.com
# 

VER="7.0"
INSTALL_DIR="/usr/share/sniper"
LOOT_DIR="$INSTALL_DIR/loot/$TARGET"
SNIPER_PRO=$INSTALL_DIR/pro.sh

# LOAD SNIPER CONFIGURATION FILE
if [ -f ~/.sniper.conf ]; then
  source ~/.sniper.conf
  echo -e "$OKBLUE[*] Loaded configuration file from ~/.sniper.conf [$RESET${OKGREEN}OK${RESET}$OKBLUE]$RESET"
else
  cp $INSTALL_DIR/sniper.conf ~/.sniper.conf 2> /dev/null
  source ~/.sniper.conf
  echo -e "$OKBLUE[*] Loaded configuration file from ~/.sniper.conf [$RESET${OKGREEN}OK${RESET}$OKBLUE]$RESET"
fi

DISTRO=$(cat /etc/*-release | grep DISTRIB_ID= | cut -d'=' -f2)

function help {
  echo -e "$OKRED                ____               $RESET"
  echo -e "$OKRED    _________  /  _/___  ___  _____$RESET"
  echo -e "$OKRED   / ___/ __ \ / // __ \/ _ \/ ___/$RESET"
  echo -e "$OKRED  (__  ) / / // // /_/ /  __/ /    $RESET"
  echo -e "$OKRED /____/_/ /_/___/ .___/\___/_/     $RESET"
  echo -e "$OKRED               /_/                 $RESET"
  echo ""
  echo -e "$OKORANGE + -- --=[https://xerosecurity.com$RESET"
  echo -e "$OKORANGE + -- --=[sniper v$VER by @xer0dayz$RESET"
  echo ""
  echo ' [*] NORMAL MODE'
  echo ' sniper -t|--target <TARGET>'
  echo ""
  echo ' [*] NORMAL MODE + OSINT + RECON'
  echo ' sniper -t|--target <TARGET> -o|--osint -re|--recon'
  echo ""
  echo ' [*] STEALTH MODE + OSINT + RECON'
  echo ' sniper -t|--target <TARGET> -m|--mode stealth -o|--osint -re|--recon'
  echo ""
  echo ' [*] DISCOVER MODE'
  echo ' sniper -t|--target <CIDR> -m|--mode discover -w|--workspace <WORSPACE_ALIAS>'
  echo ""
  echo ' [*] SCAN ONLY SPECIFIC PORT'
  echo ' sniper -t|--target <TARGET> -m port -p|--port <portnum>'
  echo ""
  echo ' [*] FULLPORTONLY SCAN MODE'
  echo ' sniper -t|--target <TARGET> -fp|--fullportonly'
  echo ""
  echo ' [*] PORT SCAN MODE'
  echo ' sniper -t|--target <TARGET> -m|--mode port -p|--port <PORT_NUM>'
  echo ""
  echo ' [*] WEB MODE - PORT 80 + 443 ONLY!'
  echo ' sniper -t|--target <TARGET> -m|--mode web'
  echo ""
  echo ' [*] HTTP WEB PORT MODE'
  echo ' sniper -t|--target <TARGET> -m|--mode webporthttp -p|--port <port>'
  echo ""
  echo ' [*] HTTPS WEB PORT MODE'
  echo ' sniper -t|--target <TARGET> -m|--mode webporthttps -p|--port <port>'
  echo ""
  echo ' [*] HTTP WEBSCAN MODE'
  echo ' sniper -t|--target <TARGET> -m|--mode webscan '
  echo ""
  echo ' [*] ENABLE BRUTEFORCE'
  echo ' sniper -t|--target <TARGET> -b|--bruteforce'
  echo ""
  echo ' [*] AIRSTRIKE MODE'
  echo ' sniper -f|--file /full/path/to/targets.txt -m|--mode airstrike'
  echo ""
  echo ' [*] NUKE MODE WITH TARGET LIST, BRUTEFORCE ENABLED, FULLPORTSCAN ENABLED, OSINT ENABLED, RECON ENABLED, WORKSPACE & LOOT ENABLED'
  echo ' sniper -f--file /full/path/to/targets.txt -m|--mode nuke -w|--workspace <WORKSPACE_ALIAS>'
  echo ""
  echo ' [*] LIST WORKSPACES'
  echo ' sniper --list'
  echo ""
  echo ' [*] DELETE WORKSPACE'
  echo ' sniper -w <WORKSPACE_ALIAS> -d'
  echo ""
  echo ' [*] DELETE HOST FROM WORKSPACE'
  echo ' sniper -w <WORKSPACE_ALIAS> -t <TARGET> -dh'
  echo ""
  echo ' [*] GET SNIPER SCAN STATUS'
  echo ' sniper --status'
  echo ""
  echo ' [*] LOOT REIMPORT FUNCTION'
  echo ' sniper -w <WORKSPACE_ALIAS> --reimport'
  echo ""
  echo ' [*] LOOT REIMPORTALL FUNCTION'
  echo ' sniper -w <WORKSPACE_ALIAS> --reimportall'
  echo ""
  echo ' [*] LOOT REIMPORT FUNCTION'
  echo ' sniper -w <WORKSPACE_ALIAS> --reload'
  echo ""
  echo ' [*] SCHEDULED SCANS'
  echo ' sniper -w <WORKSPACE_ALIAS> -s daily|weekly|monthly'
  echo ""
  echo ' [*] UPDATE SNIPER'
  echo ' sniper -u|--update'
  echo ""
  echo ""
  exit
}

function logo {
  echo -e "$OKRED                ____               $RESET"
  echo -e "$OKRED    _________  /  _/___  ___  _____$RESET"
  echo -e "$OKRED   / ___/ __ \ / // __ \/ _ \/ ___/$RESET"
  echo -e "$OKRED  (__  ) / / // // /_/ /  __/ /    $RESET"
  echo -e "$OKRED /____/_/ /_/___/ .___/\___/_/     $RESET"
  echo -e "$OKRED               /_/                 $RESET"
  echo ""
  echo -e "$OKORANGE + -- --=[https://xerosecurity.com$RESET"
  echo -e "$OKORANGE + -- --=[sniper v$VER by @xer0dayz$RESET"
  echo ""
}

function sniper_status {
  watch -n 1 -c 'ps -ef | egrep "hydra|ruby|python|dirsearch|amass|nmap|metasploit|curl|wget|nikto" && echo "NETWORK CONNECTIONS..." && netstat -an | egrep "TIME_WAIT|EST"'
}

function check_online {
  if [ ! -z "$ONLINE" ]; then
    ONLINE=$(curl --connect-timeout 3 -s https://api.github.com/repos/1N3/Sn1per/tags | grep -Po '"name":.*?[^\\]",'| head -1 | cut -c11-13)
    if [ -z "$ONLINE" ]; then
      ONLINE="0"
      echo -e "$OKBLUE[*] Checking for active internet connection [$RESET${OKRED}FAIL${RESET}$OKBLUE]"
      echo -e "$OKBLUE[$RESET${OKRED}i${RESET}$OKBLUE] sniper is running in offline mode.$RESET"
    else
      ONLINE="1"
      echo -e "$OKBLUE[*] Checking for active internet connection [$RESET${OKGREEN}OK${RESET}$OKBLUE]$RESET"
    fi
  fi
}

function check_update {
  if [ "$ENABLE_AUTO_UPDATES" == "1" ] && [ "$ONLINE" == "1" ]; then
    LATEST_VER=$(curl --connect-timeout 5 -s https://api.github.com/repos/1N3/Sn1per/tags | grep -Po '"name":.*?[^\\]",'| head -1 | cut -c11-13)
    if [ "$LATEST_VER" != "$VER" ]; then
      echo -e "$OKBLUE[$RESET${OKRED}i${RESET}$OKBLUE] sniper v$LATEST_VER is available to download... To update, type$OKRED \"sniper -u\" $RESET"
    fi
  fi
}

function update {
  logo
  echo -e "$OKBLUE[*] Checking for updates...[$RESET${OKGREEN}OK${RESET}$OKBLUE]$RESET"
  if [ "$ONLINE" == "0" ]; then
    echo "You will need to download the latest release manually at https://github.com/1N3/Sn1per/"
  else
    LATEST_VER=$(curl --connect-timeout 5 -s https://api.github.com/repos/1N3/Sn1per/tags | grep -Po '"name":.*?[^\\]",'| head -1 | cut -c11-13)
    if [ "$LATEST_VER" != "$VER" ]; then
      echo -e "$OKBLUE[$RESET${OKRED}i${RESET}$OKBLUE] Sn1per $LATEST_VER is available to download...Do you want to update? (y or n)$RESET"
      read ans
      if [ "$ans" = "y" ]; then
        rm -Rf /tmp/Sn1per/ 2>/dev/null
        git clone https://github.com/1N3/Sn1per /tmp/Sn1per/
        cd /tmp/Sn1per/
        chmod +rx install.sh
        bash install.sh
        rm -Rf /tmp/Sn1per/ 2>/dev/null
        exit
      fi
    fi
  fi
}

if [ "$UPDATE" = "1" ]; then
  update
  exit
fi

# COMMAND LINE SWITCHES
POSITIONAL=()
while [[ $# -gt 0 ]]
do
key="$1"

case $key in
    -h|--help)
    help
    shift # past argument
    ;;
    -t|--target)
    TARGET="$2"
    shift # past argument
    shift # past argument
    ;;
    -b|--bruteforce)
    AUTOBRUTE="1"
    shift # past argument
    ;;
    -fp|--fullportscan)
    FULLNMAPSCAN="1"
    shift # past argument
    ;;
    -o|--osint)
    OSINT="1"
    shift # past argument
    ;;
    -re|--recon)
    RECON="1"
    shift # past argument
    ;;
    -m|--mode)
    MODE="$2"
    shift # past argument
    shift # past argument
    ;;
    -p|--port)
    PORT="$2"
    shift # past argument
    shift # past argument
    ;;
    -f|--file)
    FILE="$(realpath $2)"
    shift # past argument
    shift # past argument
    ;;
    -ri|--reimport)
    REIMPORT="1"
    shift # past argument
    ;;
    -ria|--reimportall)
    REIMPORT_ALL="1"
    shift # past argument
    ;;
    -rl|--reload)
    RELOAD="1"
    shift # past argument
    ;;
    -n|--noreport)
    REPORT="0"
    shift # past argument
    ;;
    -nl|--noloot)
    LOOT="0"
    NOLOOT="1"
    shift # past argument
    ;;
    -w|--workspace)
    WORKSPACE="$2"
    WORKSPACE_DIR="$INSTALL_DIR/loot/workspace/$WORKSPACE"
    shift # past argument
    shift # past argument
    ;;
    -s|--schedule)
    if [ -z "$WORKSPACE" ]; then
      echo "You need to set a workspace via the -w switch to schedule a scan task."
      exit
    fi
    SCHEDULE_ARG="$2"
    if [ "$SCHEDULE_ARG" = "daily" ] || [ "$SCHEDULE_ARG" = "weekly" ] || [ "$SCHEDULE_ARG" = "monthly" ]; then
      SCHEDULE_TASK="$WORKSPACE_DIR/scans/scheduled/$SCHEDULE_ARG.sh"
      vim $SCHEDULE_TASK
      cat $WORKSPACE_DIR/scans/scheduled/*.sh 2> /dev/null
      exit
    else
      echo "You need to specify either daily, weekly or monthly for the scheduled scan argument."
      exit
    fi
    shift # past argument
    shift # past argument
    ;;
    -d|--delete)
    logo
    echo "Are you sure you want to remove the following workspace? (Hit Ctrl+C to exit): /usr/share/sniper/loot/workspace/$WORKSPACE/"
    read ANS
    rm -Rf /usr/share/sniper/loot/workspace/$WORKSPACE/
    echo "Workspace /usr/share/sniper/loot/workspace/$WORKSPACE/ was removed."
    exit
    shift # past argument
    ;;
    -dh|--delete-host)
    echo "Removing $TARGET from $WORKSPACE"
    sed -i "/$TARGET/d" $WORKSPACE_DIR/domains/targets-all-sorted.txt $WORKSPACE_DIR/domains/domains-all-sorted.txt $WORKSPACE_DIR/domains/targets.txt 2> /dev/null
    rm -f $WORKSPACE_DIR/screenshots/$TARGET*.jpg 2> /dev/null
    sniper --reimport -w $WORKSPACE 
    exit
    shift # past argument
    ;;
    --list)
    logo
    ls -l $INSTALL_DIR/loot/workspace/
    echo ""
    echo "cd /usr/share/sniper/loot/workspace/"
    WORKSPACE_REPORT=$LOOT_DIR/sniper-report.html
    if [ -f $WORKSPACE_REPORT ]; then
      echo -e "$OKORANGE + -- --=[Loading Sn1per Professional...$RESET"
      $BROWSER $INSTALL_DIR/loot/workspace/sniper-report.html 2> /dev/null > /dev/null &
    else
      echo -e "$OKORANGE + -- --=[Loading workspaces...$RESET"
      $BROWSER $INSTALL_DIR/loot/workspace/ 2> /dev/null > /dev/null &
    fi
    exit
    shift
    ;;
    -s|--status)
    sniper_status
    exit
    shift
    ;;
    -u|--update)
    UPDATE="1"
    update
    exit
    shift # past argument
    ;;
    *)    # unknown option
    POSITIONAL+=("$1") # save it in an array for later
    echo "Unknown scan option $POSITIONAL...refer to the help menu for usage details."
    exit
    shift # past argument
    ;;
esac
done
set -- "${POSITIONAL[@]}" # restore positional parameters

if [ -z "$TARGET" ] && [ -z "$WORKSPACE" ]; then
  logo
  echo "You need to specify a target or workspace to use. Type sniper --help for command usage."
  exit
fi

cd $INSTALL_DIR

function init {
  if [ ! -z $WORKSPACE_DIR ]; then
    LOOT_DIR=$WORKSPACE_DIR
  fi
  echo -e "$OKBLUE[*] Saving loot to $LOOT_DIR [$RESET${OKGREEN}OK${RESET}$OKBLUE]$RESET"
  mkdir -p $LOOT_DIR 2> /dev/nul
  mkdir $LOOT_DIR/domains 2> /dev/null
  mkdir $LOOT_DIR/ips 2> /dev/null
  mkdir $LOOT_DIR/screenshots 2> /dev/null
  mkdir $LOOT_DIR/nmap 2> /dev/null
  mkdir $LOOT_DIR/reports 2> /dev/null
  mkdir $LOOT_DIR/output 2> /dev/null
  mkdir $LOOT_DIR/osint 2> /dev/null
  mkdir $LOOT_DIR/credentials 2> /dev/null
  mkdir $LOOT_DIR/web 2> /dev/null
  mkdir $LOOT_DIR/notes 2> /dev/null
  mkdir -p $LOOT_DIR/scans/scheduled/ 2> /dev/null
  touch $LOOT_DIR/scans/scheduled/daily.sh 2> /dev/null
  touch $LOOT_DIR/scans/scheduled/weekly.sh 2> /dev/null
  touch $LOOT_DIR/scans/scheduled/monthly.sh 2> /dev/null
  TARGET="$(echo $TARGET | sed 's/https:\/\///g' | sed 's/http:\/\///g')"
  /etc/init.d/metasploit start 2> /dev/null > /dev/null 2>&1 &
  msfdb start 2> /dev/null > /dev/null

  if [ "$AUTOBRUTE" == "1" ]; then
    echo "$TARGET autobrute `date +"%Y-%m-%d %H:%M"`" 2> /dev/null >> $LOOT_DIR/scans/tasks.txt
    touch $LOOT_DIR/scans/$TARGET-autobrute.txt 2> /dev/null 
  fi

  if [ "$FULLNMAPSCAN" == "1" ]; then
    echo "$TARGET fullnmapscan `date +"%Y-%m-%d %H:%M"`" 2> /dev/null >> $LOOT_DIR/scans/tasks.txt
    touch $LOOT_DIR/scans/$TARGET-fullnmapscan.txt 2> /dev/null 
  fi

  if [ "$OSINT" == "1" ]; then
    echo "$TARGET osint `date +"%Y-%m-%d %H:%M"`" 2> /dev/null >> $LOOT_DIR/scans/tasks.txt
    touch $LOOT_DIR/scans/$TARGET-osint.txt 2> /dev/null 
  fi

  if [ "$RECON" == "1" ]; then
    echo "$TARGET recon `date +"%Y-%m-%d %H:%M"`" 2> /dev/null >> $LOOT_DIR/scans/tasks.txt
    touch $LOOT_DIR/scans/$TARGET-recon.txt 2> /dev/null 
  fi
}

function loot {
  echo -e "$OKRED                ____               $RESET"
  echo -e "$OKRED    _________  /  _/___  ___  _____$RESET"
  echo -e "$OKRED   / ___/ __ \ / // __ \/ _ \/ ___/$RESET"
  echo -e "$OKRED  (__  ) / / // // /_/ /  __/ /    $RESET"
  echo -e "$OKRED /____/_/ /_/___/ .___/\___/_/     $RESET"
  echo -e "$OKRED               /_/                 $RESET"
  echo ""
  if [ ! -z $WORKSPACE_DIR ]; then
    LOOT_DIR=$WORKSPACE_DIR
  fi

  echo -e "$OKBLUE[*] Opening loot directory $LOOT_DIR [$RESET${OKGREEN}OK${RESET}$OKBLUE]$RESET"

  cd $LOOT_DIR

  if [ "$METASPLOIT_IMPORT" == "1" ]; then
    echo -e "$OKORANGE + -- --=[Starting Metasploit service...$RESET"
    /etc/init.d/metasploit start 2> /dev/null > /dev/null
    msfdb start
    echo -e "$OKORANGE + -- --=[Importing NMap XML files into Metasploit...$RESET"
    msfconsole -x "workspace -a $WORKSPACE; workspace $WORKSPACE; db_import $LOOT_DIR/nmap/nmap*.xml; hosts; services; exit;" | tee $LOOT_DIR/notes/msf-$WORKSPACE.txt
  fi
  
  echo -e "$OKORANGE + -- --=[Generating reports...$RESET"
  cd ./output
  echo -en "$OKGREEN[$OKBLUE"
  for a in `ls sniper-*.txt 2>/dev/null`;
  #for a in `sort -u $LOOT_DIR/scans/updated.txt`;
  do
    # TXT OUTPUT
    #cat "$a" 2> /dev/null | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" 2> /dev/null > $LOOT_DIR/reports/$a.txt 2> /dev/null 
    # HTML OUTPUT
    echo "$a" 2> /dev/null | aha 2> /dev/null > $LOOT_DIR/reports/$a.html 2> /dev/null
    cat "$a" 2> /dev/null | aha 2> /dev/null >> $LOOT_DIR/reports/$a.html 2> /dev/null
    # PDF OUTPUT
    #$INSTALL_DIR/bin/pyText2pdf.py -o $LOOT_DIR/reports/$a.pdf $LOOT_DIR/reports/$a.txt 2> /dev/null > /dev/null
    echo -n '|'
  done
  echo -en "$OKGREEN]$RESET"
  echo ""
  cd ..
  echo -e "$OKORANGE + -- --=[Sorting all domains...$RESET"
  #touch $LOOT_DIR/domains/domains-all-sorted.txt 2> /dev/null
  sort -u $LOOT_DIR/domains/*-full.txt > $LOOT_DIR/domains/domains-all-presorted.txt 2> /dev/null
  sed -E "s/^\.//g" $LOOT_DIR/domains/domains-all-presorted.txt | sed -E "s/^\*\.//g" |  tr '[:upper:]' '[:lower:]' | sort -u > $LOOT_DIR/domains/domains-all-presorted2.txt 2> /dev/null
  sort -u $LOOT_DIR/domains/targets.txt > $LOOT_DIR/domains/targets-all-presorted.txt 2> /dev/null
  sed -E "s/^\.//g" $LOOT_DIR/domains/targets-all-presorted.txt | sed -E "s/^\*\.//g" |  tr '[:upper:]' '[:lower:]' | sort -u > $LOOT_DIR/domains/targets-all-sorted.txt 2> /dev/null
  sort -u $LOOT_DIR/ips/ips-all-unsorted.txt 2> /dev/null > $LOOT_DIR/ips/ips-all-sorted.txt 2> /dev/null
  sed -i -E 's/address//g' $LOOT_DIR/ips/ips-all-sorted.txt 2> /dev/null
  sort -u $LOOT_DIR/domains/domains-all-presorted2.txt $LOOT_DIR/domains/targets-all-sorted.txt 2> /dev/null > $LOOT_DIR/domains/domains-all-sorted.txt 2> /dev/null
  diff $LOOT_DIR/domains/targets-all-sorted.txt $LOOT_DIR/domains/domains-all-sorted.txt | grep \> | awk '{print $2}' > $LOOT_DIR/domains/targets-all-unscanned.txt
  echo -e "$OKORANGE + -- --=[Removing blank screenshots...$RESET"
  cd $LOOT_DIR/screenshots/
  find $LOOT_DIR/screenshots/ -type f -size -9000c -exec rm -f {} \;
  cd $LOOT_DIR
  if [ -f $SNIPER_PRO ]; then
    if [ "$SN1PER_AUTOLOAD" = "1" ]; then
      echo -e "$OKORANGE + -- --=[Loading Sn1per Professional...$RESET"
      source $INSTALL_DIR/pro.sh
      $BROWSER $LOOT_DIR/sniper-report.html 2> /dev/null > /dev/null &
    else
      echo -e "$OKORANGE + -- --=[Do you want to load Sn1per Professional (y or n)? $RESET"
      read ANS
      if [ "$ANS" == "y" ]; then
        echo -e "$OKORANGE + -- --=[Loading Sn1per Professional...$RESET"
        source $INSTALL_DIR/pro.sh
        $BROWSER $LOOT_DIR/sniper-report.html 2> /dev/null > /dev/null &
      else 
        echo -e "$OKORANGE + -- --=[Skipping report generation. $RESET"
      fi
    fi
  else
    echo -e "$OKRED + -- --=[Sn1per Professional is not installed. To download Sn1per Professional, go to https://xerosecurity.com. $RESET"
    $BROWSER https://xerosecurity.com 2> /dev/null > /dev/null &
  fi
  echo -e "$OKORANGE + -- --=[Done!$RESET"
}

if [ "$REIMPORT" = "1" ]; then
  if [ ! -z "$WORKSPACE_DIR" ]; then
    loot
    exit
  fi
fi

if [ "$REIMPORT_ALL" = "1" ]; then
  if [ ! -z "$WORKSPACE_DIR" ]; then
    sort -u $WORKSPACE_DIR/domains/targets-all-sorted.txt $WORKSPACE_DIR/domains/domains-all-sorted.txt > $WORKSPACE_DIR/scans/updated.txt
    loot
    exit
  fi
fi

if [ "$RELOAD" = "1" ]; then
  if [ ! -z "$WORKSPACE_DIR" ]; then
    $BROWSER $WORKSPACE_DIR/sniper-report.html 2> /dev/null > /dev/null &
    exit
  fi
fi

if [[ ${TARGET:0:1} =~ $REGEX ]];
then
  SCAN_TYPE="IP"
  
else
  SCAN_TYPE="DOMAIN"
fi

# INITILIZE
init

# CHECK CONNECTION STATUS
check_online

# CHECK FOR UPDATES
check_update

# CHECK FOR BLACKARCH LINUX
if grep -q BlackArch /etc/issue; then
  DISTRO='blackarch'
  echo "Detected BlackArch GNU/Linux"
  INSTALL_DIR=$(pwd)
  echo "Setting current path to $INSTALL_DIR"
fi

source modes/discover.sh
source modes/flyover.sh
source modes/fullportonly.sh
source modes/web.sh
source modes/webporthttp.sh
source modes/webporthttps.sh
source modes/webscan.sh
source modes/stealth.sh
source modes/airstrike.sh
source modes/nuke.sh
source modes/normal.sh

exit 0
